/*
* INSANE - Interactive Structural Analysis Environment
*
* Copyright (C) 2003-2005
* Universidade Federal de Minas Gerais
* Escola de Engenharia
* Departamento de Engenharia de Estruturas
* 
* Author's email :    insane@dees.ufmg.br
* Author's website :  http://www.dees.ufmg.br/insane
* 
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or any later version.
* 
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
* 
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/
package br.ufmg.dees.insane.ui.rich.learn.learn_view.command;
import java.io.File;
import java.io.IOException;
import java.util.StringTokenizer;

import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import br.ufmg.dees.insane.crossSection.CrossSection;
import br.ufmg.dees.insane.crossSection.RegCrossSection;
import br.ufmg.dees.insane.materialMedia.material.LinearElasticIsotropic;
import br.ufmg.dees.insane.materialMedia.material.MSpring;
import br.ufmg.dees.insane.model.disc.analysismodel.AnalysisModel;
import br.ufmg.dees.insane.model.disc.analysismodel.AxiSymetricAnalysisM;
import br.ufmg.dees.insane.model.disc.analysismodel.Beam;
import br.ufmg.dees.insane.model.disc.analysismodel.Grid;
import br.ufmg.dees.insane.model.disc.analysismodel.Line_1D;
import br.ufmg.dees.insane.model.disc.analysismodel.Line_2D;
import br.ufmg.dees.insane.model.disc.analysismodel.Line_3D;
import br.ufmg.dees.insane.model.disc.analysismodel.PlaneFrame;
import br.ufmg.dees.insane.model.disc.analysismodel.PlaneStrainAnalysisM;
import br.ufmg.dees.insane.model.disc.analysismodel.PlaneStressAnalysisM;
import br.ufmg.dees.insane.model.disc.analysismodel.PlaneTruss;
import br.ufmg.dees.insane.model.disc.analysismodel.SolidAnalysisM;
import br.ufmg.dees.insane.model.disc.analysismodel.SpaceFrame;
import br.ufmg.dees.insane.model.disc.analysismodel.SpaceTruss;
import br.ufmg.dees.insane.model.disc.driver.Driver;
import br.ufmg.dees.insane.model.disc.driver.StructuralMech;
import br.ufmg.dees.insane.model.disc.element.Element;
import br.ufmg.dees.insane.model.disc.element.ElmAxiQ4;
import br.ufmg.dees.insane.model.disc.element.ElmAxiQ8;
import br.ufmg.dees.insane.model.disc.element.ElmAxiQ9;
import br.ufmg.dees.insane.model.disc.element.ElmH20;
import br.ufmg.dees.insane.model.disc.element.ElmH8;
import br.ufmg.dees.insane.model.disc.element.ElmL2;
import br.ufmg.dees.insane.model.disc.element.ElmL3;
import br.ufmg.dees.insane.model.disc.element.ElmL4;
import br.ufmg.dees.insane.model.disc.element.ElmQ4;
import br.ufmg.dees.insane.model.disc.element.ElmQ8;
import br.ufmg.dees.insane.model.disc.element.ElmQ9;
import br.ufmg.dees.insane.model.disc.element.ElmT10;
import br.ufmg.dees.insane.model.disc.element.ElmT3;
import br.ufmg.dees.insane.model.disc.element.ElmT6;
import br.ufmg.dees.insane.model.disc.element.ElmTetra4;
import br.ufmg.dees.insane.model.disc.element.FrameElement;
import br.ufmg.dees.insane.model.disc.element.ParametricElement;
import br.ufmg.dees.insane.model.disc.element.force.ElementForce;
import br.ufmg.dees.insane.model.disc.fem.FemModel;
import br.ufmg.dees.insane.model.disc.integrationorder.IntegrationOrder;
import br.ufmg.dees.insane.model.disc.node.Node;
import br.ufmg.dees.insane.model.disc.pointforce.PointForce;
import br.ufmg.dees.insane.model.disc.shape.H20;
import br.ufmg.dees.insane.model.disc.shape.H8;
import br.ufmg.dees.insane.model.disc.shape.L2;
import br.ufmg.dees.insane.model.disc.shape.L3;
import br.ufmg.dees.insane.model.disc.shape.L4;
import br.ufmg.dees.insane.model.disc.shape.Q4;
import br.ufmg.dees.insane.model.disc.shape.Q8;
import br.ufmg.dees.insane.model.disc.shape.Q9;
import br.ufmg.dees.insane.model.disc.shape.Shape;
import br.ufmg.dees.insane.model.disc.shape.T10;
import br.ufmg.dees.insane.model.disc.shape.T3;
import br.ufmg.dees.insane.model.disc.shape.T6;
import br.ufmg.dees.insane.model.disc.shape.Tetra4;
import br.ufmg.dees.insane.ui.rich.learn.learn_view.ExtensionFileFilter;
import br.ufmg.dees.insane.ui.rich.learn.learn_view.LearnInterface;
import br.ufmg.dees.insane.util.IPoint3d;

/**
 * This class is an implementation of the interface Command.
 * It's unabled to undo or redo.
 * Its "execute" method fills the current fem model with
 * the data from a XML file in a given file.
 *
 * @author Fonseca, Flavio & Pitangueira, Roque
 * @since February 2004
 * @see gui.command.Command
 */
public class ImportXMLCommand implements Command {
    
    private LearnInterface parent;
    private JFileChooser fileChooser = new JFileChooser();
    private ExtensionFileFilter filter = new ExtensionFileFilter(new String[]{"xml"}, "XML Files");
	private Driver driver;
	
	private static int MAT_ISOTROPIC = 1;
	private static int MAT_MSPRING = 2;
	private static int ELM_FRAME = 1;
	private static int ELM_PARAMETRIC = 2;
	
//*****************************************************************************
	
    /**
     * Creates new ImportXMLCommand
     * and sets the FileFilter of FileChooser.
     *
     * @param parent The JFrame parent.
     */
    public ImportXMLCommand(JFrame parent) {
        this.parent = (LearnInterface)parent;
        fileChooser.setFileFilter(filter);
    }
    
//*****************************************************************************
	
    /**
     * Calls the file chooser an encode the fem model as a XML file.
     *
     * @see gui.command.Command#execute()
     */
    public void execute() {
		Command cmd = new NewFileCommand(parent);
		cmd.execute();
		
		fileChooser.setDialogTitle("Import XML");
		int retVal = fileChooser.showDialog(parent, "Import");
		
        if (retVal == JFileChooser.APPROVE_OPTION) {
            
			//Getting the file name
            String s = fileChooser.getSelectedFile().getName();
            
			//Getting the file extension
            String ext = new String();
            int i = s.lastIndexOf('.');
            if (i > 0 &&  i < s.length() - 1) {
                ext = s.substring(i+1).toLowerCase();
            }
            
			//Comparing the extension
            if (!ext.equals("xml")) {
                s = s + ".xml";
                File file = fileChooser.getSelectedFile();
                
				//Changing the file in case of no good extensions
                fileChooser.setSelectedFile(new File(file.getParent() + File.separator + s));
            }
			
			try {
				buildDriverFromXML(fileChooser.getSelectedFile());
				//parent.getModel().setDriver(driver);
				parent.addOutputText("File \"" + fileChooser.getSelectedFile().getPath() + "\" successfully imported.");
				parent.addOutputText("Automatic Processor");
				parent.getView().getViewState();
				parent.getSplitPane().setDividerLocation(230);
				Command cmd2 = new FitCommand(parent);
				cmd2.execute();
			} catch (NullPointerException e) {
				parent.addOutputText("ERROR - Could not import XML file.");
			}
        }
    }
    
//*****************************************************************************
	
    /**
     * Impossible to undo - not implemented.
     */
    public void undo() {}
    
//*****************************************************************************
	
    /**
     * Impossible to redo - not implemented.
     */
    public void redo() {}
    
//*****************************************************************************
	
	/** Builds the DiscreteModel from the data in a XML file.
	*@param XMLFile The input XML file.
	*/
	public void buildDriverFromXML(File XMLFile) {
		
		//Creating and configuring the SAXParser
		SAXParserFactory parserFac = SAXParserFactory.newInstance();
		parserFac.setValidating(true);
		try {
			SAXParser parser = parserFac.newSAXParser();
			
			//implementing DefaultHandler
			parser.parse(XMLFile, new DefaultHandler() {
				StringBuffer content = new StringBuffer();
				
				//All the classes which will be instantiated are declared here
				//Solution solution;
				FemModel model;
				Node node;
				IPoint3d coord;
				CrossSection cs;
				LinearElasticIsotropic matIso;
				MSpring matSpr;
				AnalysisModel anl;
				Element elm;
				Shape shp;
				PointForce elmPF;
				ElementForce ef;
				StringTokenizer stk;
				PointForce pf;
				IntegrationOrder intOr;
				
				int matType;
				int elmType;
				
				public void setDocumentLocator(Locator locator) {
				}
				
				public void characters(char ch[], int start, int lenght) {
					this.content.append(ch, start, lenght);
				}
				
				public void startElement(String uri, String localName, String qName, Attributes attributes) {
				
					//Read "<Driver ...>"
					if ("Driver".equals(qName)) {
						if (attributes.getValue("class").equals("StructuralMech")) {
							driver = new StructuralMech();
						}
					}
					
					//Read "<Solution ...>"
					/*else if ("Solution".equals(qName)) {
						if (attributes.getValue("class").equals("OnePointEq")) {
							 solution = new OnePointEq();
						}
					}*/
					
					//Read "<Model ...>"
					else if ("Model".equals(qName)) {
						model = new FemModel();
					}
					
					//Read "<NodeList ...>"
					else if ("NodeList".equals(qName)) {
					}
					
					//Read "<MaterialList ...>"
					else if ("MaterialList".equals(qName)) {
					}
					
					//Read "<CrossSectionList ...>"
					else if ("CrossSectionList".equals(qName)) {
					}
					
					//Read "<ElementList ...>"
					else if ("ElementList".equals(qName)) {
					}
					
					//Read "<Node ...>"
					else if ("Node".equals(qName)) {
						node = new Node();
						node.setLabel(attributes.getValue("label"));
					}
					
					//Read "<Material ...>"
					else if ("Material".equals(qName)) {
						if (attributes.getValue("class").equals("Isotropic")) {
							matIso = new LinearElasticIsotropic();
							//matIso.setLabel(attributes.getValue("label"));
							matType = MAT_ISOTROPIC;
						}
						if (attributes.getValue("class").equals("MSpring")) {
							matSpr = new MSpring();
							//matSpr.setLabel(attributes.getValue("label"));
							matType = MAT_MSPRING;
						}
					}
					
					//Read "<CrossSection ...>"
					else if ("CrossSection".equals(qName)) {
						cs = new RegCrossSection();
						cs.setLabel(attributes.getValue("label"));
					}
					
					//Read "<Element ...>"
					else if ("Element".equals(qName)) {
						if (attributes.getValue("class").equals("FrameElement")) {
							elm = new FrameElement();
							elmType = ELM_FRAME;
						}
						if (attributes.getValue("class").equals("ParametricElement.Quadrilateral.Q4")) {
							shp = new Q4();
							model.add(shp);
							elm = new ElmQ4(model.getShape("Q4"));
							elmType = ELM_PARAMETRIC;
						}
						if (attributes.getValue("class").equals("ParametricElement.Quadrilateral.Q8")) {
							shp = new Q8();
							model.add(shp);
							elm = new ElmQ8(model.getShape("Q8"));
							elmType = ELM_PARAMETRIC;
						}
						if (attributes.getValue("class").equals("ParametricElement.Quadrilateral.Q9")) {
							shp = new Q9();
							model.add(shp);
							elm = new ElmQ9(model.getShape("Q9"));
							elmType = ELM_PARAMETRIC;
						}
						if (attributes.getValue("class").equals("ParametricElement.Triangular.T3")) {
							shp = new T3();
							model.add(shp);
							elm = new ElmT3(model.getShape("T3"));
							elmType = ELM_PARAMETRIC;
						}
						if (attributes.getValue("class").equals("ParametricElement.Triangular.T6")) {
							shp = new T6();
							model.add(shp);
							elm = new ElmT6(model.getShape("T6"));
							elmType = ELM_PARAMETRIC;
						}
						if (attributes.getValue("class").equals("ParametricElement.Triangular.T10")) {
							shp = new T10();
							model.add(shp);
							elm = new ElmT10(model.getShape("T10"));
							elmType = ELM_PARAMETRIC;
						}
						if (attributes.getValue("class").equals("ParametricElement.Hexahedral.H8")) {
							shp = new H8();
							model.add(shp);
							elm = new ElmH8(model.getShape("H8"));
							elmType = ELM_PARAMETRIC;
						}
						if (attributes.getValue("class").equals("ParametricElement.Hexahedral.H20")) {
							shp = new H20();
							model.add(shp);
							elm = new ElmH20(model.getShape("H20"));
							elmType = ELM_PARAMETRIC;
						}
						if (attributes.getValue("class").equals("ParametricElement.Tetrahedral.Tetra4")) {
							shp = new Tetra4();
							model.add(shp);
							elm = new ElmTetra4(model.getShape("Tetra4"));
							elmType = ELM_PARAMETRIC;
						}
						if (attributes.getValue("class").equals("ParametricElement.Quadrilateral.AxiQ4")) {
							shp = new Q4();
							model.add(shp);
							elm = new ElmAxiQ4(model.getShape("Q4"));
							elmType = ELM_PARAMETRIC;
						}
						if (attributes.getValue("class").equals("ParametricElement.Quadrilateral.AxiQ8")) {
							shp = new Q8();
							model.add(shp);
							elm = new ElmAxiQ8(model.getShape("Q8"));
							elmType = ELM_PARAMETRIC;
						}
						if (attributes.getValue("class").equals("ParametricElement.Quadrilateral.AxiQ9")) {
							shp = new Q9();
							model.add(shp);
							elm = new ElmAxiQ9(model.getShape("Q9"));
							elmType = ELM_PARAMETRIC;
						}
						if (attributes.getValue("class").equals("ParametricElement.Bar.L2")) {
							shp = new L2();
							model.add(shp);
							elm = new ElmL2(model.getShape("L2"));
							elmType = ELM_PARAMETRIC;
						}
						if (attributes.getValue("class").equals("ParametricElement.Bar.L3")) {
							shp = new L3();
							model.add(shp);
							elm = new ElmL3(model.getShape("L3"));
							elmType = ELM_PARAMETRIC;
						}
						if (attributes.getValue("class").equals("ParametricElement.Bar.L4")) {
							shp = new L4();
							model.add(shp);
							elm = new ElmL4(model.getShape("L4"));
							elmType = ELM_PARAMETRIC;
						}
						elm.setLabel(attributes.getValue("label"));
					}
					
					//Read "<Coord ...>"
					else if ("Coord".equals(qName)) {
						coord = new IPoint3d();
					}
					
					//Read "<Restraints ...>"
					else if ("Restraints".equals(qName)) {
					}
					
					//Read "<Load ...>"
					else if ("Load".equals(qName)) {
					}
					
					//Read "<PreDisplacements ...>"
					else if ("PreDisplacements".equals(qName)) {
					}
					
					//Read "<mySpring ...>"
					else if ("mySpring".equals(qName)) {
					}
					
					//Read "<Angle ...>"
					else if ("Angle".equals(qName)) {
					}
					
					//Read "<Elasticity ...>"
					else if ("Elasticity".equals(qName)) {
					}
					
					//Read "<Poisson ...>"
					else if ("Poisson".equals(qName)) {
					}
					
					//Read "<Stiffness ...>"
					else if ("Stiffness".equals(qName)) {
					}
					
					//Read "<ThermalCoeff ...>"
					else if ("ThermalCoeff".equals(qName)) {
					}
					
					//Read "<G ...>"
					else if ("G".equals(qName)) {
					}
					
					//Read "<Ix ...>"
					else if ("Ix".equals(qName)) {
					}
					
					//Read "<Iy ...>"
					else if ("Iy".equals(qName)) {
					}
					
					//Read "<Iz ...>"
					else if ("Iz".equals(qName)) {
					}
					
					//Read "<Height ...>"
					else if ("Height".equals(qName)) {
					}
					
					//Read "<Area ...>"
					else if ("Area".equals(qName)) {
					}
					
					//Read "<Thickness>"
					else if ("Thickness".equals(qName)) {
					}
					
					//Read "<IntegrationOrder>"
					else if ("IntegrationOrder".equals(qName)){
					}
					
					//Read "<Incidence ...>"
					else if ("Incidence".equals(qName)) {
					}
					
					//Read "<MyMaterial ...>"
					else if ("MyMaterial".equals(qName)) {
					}
					
					//Read "<MyCrossSection ...>"
					else if ("MyCrossSection".equals(qName)) {
					}
					
					//Read "<MyAnalysisModel ...>"
					else if ("MyAnalysisModel".equals(qName)) {
					}
					
					//Read "<DeltaTemp ...>"
					else if ("DeltaTemp".equals(qName)) {
					}
					
					//Read "<ElmPreDisplacement ...>"
					else if ("ElmPreDisplacement".equals(qName)) {
					}
					
					//Read "<InitialNodalForce ...>"
					else if ("InitialNodalForce".equals(qName)) {
					}
					
					//Read "<Liberations ...>"
					else if ("Liberations".equals(qName)) {
					}
					
					//Read "<MyElmPointForce ...>"
					else if ("MyElmPointForce".equals(qName)) {
					}
					
					//Read "<MyLineForce ...>"
					else if ("MyLineForce".equals(qName)) {
					}
					
					//Read "<MySurfaceForce ...>"
					else if ("MySurfaceForce".equals(qName)) {
					}
					
					//Read "<MyVolumeForce ...>"
					else if ("MyVolumeForce".equals(qName)) {
					}
					
					//Read "<LineElementForce ...>"
					else if ("LineElementForce".equals(qName)) {
						ef = new ElementForce();
					}
					
					//Read "<SurfaceElementForce ...>"
					else if ("SurfaceElementForce".equals(qName)) {
						ef = new ElementForce();
					}
					
					//Read "<VolumeElementForce ...>"
					else if ("VolumeElementForce".equals(qName)) {
						ef = new ElementForce();
					}
					
					//Read "<ElmPointForce ...>"
					else if ("ElmPointForce".equals(qName)) {
						elmPF = new PointForce();
					}
					
					//Read "<Point ...>"
					else if ("Point".equals(qName)) {
						coord = new IPoint3d();
					}
					
					//Read "<Force ...>"
					else if ("Force".equals(qName)) {
					}
					
					//Read "<PointForce ...>"
					else if ("PointForce".equals(qName)) {
						pf = new PointForce();
					}
					
					//Read "<PointForceCoords ...>"
					else if ("PointForceCoords".equals(qName)) {
						coord = new IPoint3d();
					}
					
					//Read "<PointForceLoad ...>"
					else if ("PointForceLoad".equals(qName)) {
					}
					
					//Read "<GlobalAnalysisModel ...>"
					else if ("GlobalAnalysisModel".equals(qName)) {
					}
				
				}
				
				@SuppressWarnings("unchecked")
				public void endElement(String uri, String localName, String qName) {
				
					//Read "</Driver>"
					if ("Driver".equals(qName)) {
					}
					
					//Read "</Model>"
					else if ("Model".equals(qName)) {
						driver.setFemModel(model);
					}
					
					//Read "</Solution>"
					/*else if ("Solution".equals(qName)) {
						driver.setSolution(solution);
					}*/
					
					//Read "</NodeList>"
					else if ("NodeList".equals(qName)) {
					}
					
					//Read "</MaterialList>"
					else if ("MaterialList".equals(qName)) {
					}
					
					//Read "</CrossSectionList>"
					else if ("CrossSectionList".equals(qName)) {
					}
					
					//Read "</ElementList>"
					else if ("ElementList".equals(qName)) {
					}
					
					//Read "</Node>"
					else if ("Node".equals(qName)) {
						model.add(node);
					}
					
					//Read "</Material>"
					else if ("Material".equals(qName)) {
						if (matType==MAT_ISOTROPIC)
							model.add(matIso);
						if (matType==MAT_MSPRING)
							model.add(matSpr);
					}
					
					//Read "</CrossSection>"
					else if ("CrossSection".equals(qName)) {
						model.add(cs);
					}
					
					//Read "</Element>"
					else if ("Element".equals(qName)) {
						if (elmType==ELM_FRAME) {
							try {
								((FrameElement)elm).setLenght();
								((FrameElement)elm).setShape(model);
							} catch (Exception e) {}
						}
						model.add(elm);
					}
					
					//Read "</Coord>"
					else if ("Coord".equals(qName)) {
						stk = new StringTokenizer(content.toString(), " ");
						coord.x = Double.parseDouble(stk.nextToken());
						coord.y = Double.parseDouble(stk.nextToken());
						if (stk.hasMoreTokens())
							coord.z = Double.parseDouble(stk.nextToken());
						node.setCoord(coord);
					}
					
					//Read "</Restraints>"
					else if ("Restraints".equals(qName)) {
						stk = new StringTokenizer(content.toString(), " ");
						
						if (stk.nextToken().toLowerCase().equals("true"))
							node.setRestraint(0, true);
						else node.setRestraint(0, false);
						
						if (stk.nextToken().toLowerCase().equals("true"))
							node.setRestraint(1, true);
						else node.setRestraint(1, false);
						
						if (stk.nextToken().toLowerCase().equals("true"))
							node.setRestraint(2, true);
						else node.setRestraint(2, false);
						
						if (stk.nextToken().toLowerCase().equals("true"))
							node.setRestraint(3, true);
						else node.setRestraint(3, false);
						
						if (stk.nextToken().toLowerCase().equals("true"))
							node.setRestraint(4, true);
						else node.setRestraint(4, false);
						
						if (stk.nextToken().toLowerCase().equals("true"))
							node.setRestraint(5, true);
						else node.setRestraint(5, false);
					}
					
					//Read "</Load>"
					else if ("Load".equals(qName)) {
						stk = new StringTokenizer(content.toString(), " ");
						node.setForce(0, Double.parseDouble(stk.nextToken()));
						node.setForce(1, Double.parseDouble(stk.nextToken()));
						node.setForce(2, Double.parseDouble(stk.nextToken()));
						node.setForce(3, Double.parseDouble(stk.nextToken()));
						node.setForce(4, Double.parseDouble(stk.nextToken()));
						node.setForce(5, Double.parseDouble(stk.nextToken()));
					}
					
					//Read "</PreDisplacements>"
					else if ("PreDisplacements".equals(qName)) {
						stk = new StringTokenizer(content.toString(), " ");
						node.setPreDisplacement(0, Double.parseDouble(stk.nextToken()));
						node.setPreDisplacement(1, Double.parseDouble(stk.nextToken()));
						node.setPreDisplacement(2, Double.parseDouble(stk.nextToken()));
						node.setPreDisplacement(3, Double.parseDouble(stk.nextToken()));
						node.setPreDisplacement(4, Double.parseDouble(stk.nextToken()));
						node.setPreDisplacement(5, Double.parseDouble(stk.nextToken()));
					}
					
					//Read "</mySpring>"
					else if ("mySpring".equals(qName)) {
						stk = new StringTokenizer(content.toString(), " ");
						node.setSpring(0, Double.parseDouble(stk.nextToken()));
						node.setSpring(1, Double.parseDouble(stk.nextToken()));
						node.setSpring(2, Double.parseDouble(stk.nextToken()));
						node.setSpring(3, Double.parseDouble(stk.nextToken()));
						node.setSpring(4, Double.parseDouble(stk.nextToken()));
						node.setSpring(5, Double.parseDouble(stk.nextToken()));
					}
					
					//Read "</Angle>"
					else if ("Angle".equals(qName)) {
						node.setAngle(Double.parseDouble(content.toString()));
					}
					
					//Read "</Elasticity>"
					else if ("Elasticity".equals(qName)) {
					    matIso.setMaterialValues(matIso.ELASTICITY,Double.parseDouble(content.toString()));
					}
					
					//Read "</Poisson>"
					else if ("Poisson".equals(qName)) {
					    matIso.setMaterialValues(matIso.POISSON,Double.parseDouble(content.toString()));
					}
					
					//Read "</Stiffness>"
					else if ("Stiffness".equals(qName)) {
						stk = new StringTokenizer(content.toString(), " ");
						matSpr.setStiffness(0, Double.parseDouble(stk.nextToken()));
						matSpr.setStiffness(1, Double.parseDouble(stk.nextToken()));
						matSpr.setStiffness(2, Double.parseDouble(stk.nextToken()));
						matSpr.setStiffness(3, Double.parseDouble(stk.nextToken()));
						matSpr.setStiffness(4, Double.parseDouble(stk.nextToken()));
						matSpr.setStiffness(5, Double.parseDouble(stk.nextToken()));
					}
					
					//Read "</ThermalCoeff>"
					else if ("ThermalCoeff".equals(qName)) {
					    matIso.setMaterialValues(matIso.THERMAL_COEFF,Double.parseDouble(content.toString()));
					}
					
					//Read "</G>"
					else if ("G".equals(qName)) {
					    matIso.setMaterialValues(matIso.SHEAR_MODULUS,Double.parseDouble(content.toString()));
					}
					
					//Read "</Ix>"
					else if ("Ix".equals(qName)) {
						cs.setIx(Double.parseDouble(content.toString()));
					}
					
					//Read "</Iy>"
					else if ("Iy".equals(qName)) {
						cs.setIy(Double.parseDouble(content.toString()));
					}
					
					//Read "</Iz>"
					else if ("Iz".equals(qName)) {
						cs.setIz(Double.parseDouble(content.toString()));
					}
					
					//Read "</Height>"
					else if ("Height".equals(qName)) {
						cs.setHeight(Double.parseDouble(content.toString()));
					}
					
					//Read "</Area>"
					else if ("Area".equals(qName)) {
						cs.setArea(Double.parseDouble(content.toString()));
					}
					
					//Read "</Thickness>"
					else if ("Thickness".equals(qName)) {
						cs.setThickness(Double.parseDouble(content.toString()));
					}
					
					//Read "</IntegrationOrder>"
					else if (elmType==ELM_PARAMETRIC && "IntegrationOrder".equals(qName)) {
						stk = new StringTokenizer(content.toString(), " ");
						intOr = new IntegrationOrder((int)(Double.parseDouble(stk.nextToken())),(int)(Double.parseDouble(stk.nextToken())),(int)(Double.parseDouble(stk.nextToken())));
						model.add(intOr);
						((ParametricElement)elm).setIntegrationOrder(model.getIntegrationOrder(content.toString()));
						((ParametricElement)elm).generateIntegrationPoints();
					}
					
					//Read "</Incidence>"
					else if ("Incidence".equals(qName)) {
						stk = new StringTokenizer(content.toString(), " ");
						int i = 0;
						while (stk.hasMoreTokens()) {
							elm.getIncidence().add(i, model.getNode(stk.nextToken()));
							i++;
						}
					}
					
					//Read "</MyMaterial>"
					else if ("MyMaterial".equals(qName)) {
						String label = content.toString();
						elm.setMaterial(model.getMaterial(label));
					}
					
					//Read "</MyCrossSection>"
					else if ("MyCrossSection".equals(qName)) {
						String label = content.toString();
						elm.setCrossSection(model.getCrossSection(label));
					}
					
					//Read "</MyAnalysisModel>"
					else if ("MyAnalysisModel".equals(qName)) {
						String type = content.toString();
						if (model.getAnalysisModel(type) != null)
							elm.setAnalysisModel(model.getAnalysisModel(type));
						else {
							if (type.equals("PlaneFrame")) {
								anl = new PlaneFrame();
								model.add(anl);
							} else if (type.equals("PlaneTruss")) {
								anl = new PlaneTruss();
								model.add(anl);
							} else if (type.equals("Grid")) {
								anl = new Grid();
								model.add(anl);
							} else if (type.equals("Beam")) {
								anl = new Beam();
								model.add(anl);
							} else if (type.equals("SpaceFrame")) {
								anl = new SpaceFrame();
								model.add(anl);
							} else if (type.equals("SpaceTruss")) {
								anl = new SpaceTruss();
								model.add(anl);
							} else if (content.toString().equals("Line_1D")) {
								 anl = new Line_1D();
								 model.add(anl);
							} else if (content.toString().equals("Line_2D")) {
								 anl = new Line_2D();
								 model.add(anl);
							} else if (content.toString().equals("Line_3D")) {
								 anl = new Line_3D();
								 model.add(anl);
							} else if (content.toString().equals("PlaneStrainAnalysisM")) {
								 anl = new PlaneStrainAnalysisM();
								 model.add(anl);
							} else if (content.toString().equals("PlaneStressAnalysisM")) {
								 anl = new PlaneStressAnalysisM();
								 model.add(anl);
							} else if (content.toString().equals("AxiSymetricAnalysisM")) {
								 anl = new AxiSymetricAnalysisM();
								 model.add(anl);
							} else if (content.toString().equals("SolidAnalysisM")) {
								 anl = new SolidAnalysisM();
								 model.add(anl);
							}
							
							elm.setAnalysisModel(anl);
						}
					}
					
					//Read "</DeltaTemp>"
					else if (elmType==ELM_FRAME && "DeltaTemp".equals(qName)) {
						stk = new StringTokenizer(content.toString(), " ");
						((FrameElement)elm).setDeltaTemp(0, Double.parseDouble(stk.nextToken()));
						((FrameElement)elm).setDeltaTemp(1, Double.parseDouble(stk.nextToken()));
						((FrameElement)elm).setDeltaTemp(2, Double.parseDouble(stk.nextToken()));
					}
					
					//Read "</ElmPreDisplacement>"
					else if (elmType==ELM_FRAME && "ElmPreDisplacement".equals(qName)) {
						stk = new StringTokenizer(content.toString(), " ");
						((FrameElement)elm).setElmPreDisplacement(0, Double.parseDouble(stk.nextToken()));
						((FrameElement)elm).setElmPreDisplacement(1, Double.parseDouble(stk.nextToken()));
						((FrameElement)elm).setElmPreDisplacement(2, Double.parseDouble(stk.nextToken()));
						((FrameElement)elm).setElmPreDisplacement(3, Double.parseDouble(stk.nextToken()));
						((FrameElement)elm).setElmPreDisplacement(4, Double.parseDouble(stk.nextToken()));
						((FrameElement)elm).setElmPreDisplacement(5, Double.parseDouble(stk.nextToken()));
						((FrameElement)elm).setElmPreDisplacement(6, Double.parseDouble(stk.nextToken()));
						((FrameElement)elm).setElmPreDisplacement(7, Double.parseDouble(stk.nextToken()));
						((FrameElement)elm).setElmPreDisplacement(8, Double.parseDouble(stk.nextToken()));
						((FrameElement)elm).setElmPreDisplacement(9, Double.parseDouble(stk.nextToken()));
						((FrameElement)elm).setElmPreDisplacement(10, Double.parseDouble(stk.nextToken()));
						((FrameElement)elm).setElmPreDisplacement(11, Double.parseDouble(stk.nextToken()));
					}
					
					//Read "</InitialNodalForce>"
					else if (elmType==ELM_FRAME && "InitialNodalForce".equals(qName)) {
						stk = new StringTokenizer(content.toString(), " ");
						((FrameElement)elm).setInitialNodalForce(0, Double.parseDouble(stk.nextToken()));
						((FrameElement)elm).setInitialNodalForce(1, Double.parseDouble(stk.nextToken()));
						((FrameElement)elm).setInitialNodalForce(2, Double.parseDouble(stk.nextToken()));
						((FrameElement)elm).setInitialNodalForce(3, Double.parseDouble(stk.nextToken()));
						((FrameElement)elm).setInitialNodalForce(4, Double.parseDouble(stk.nextToken()));
						((FrameElement)elm).setInitialNodalForce(5, Double.parseDouble(stk.nextToken()));
						((FrameElement)elm).setInitialNodalForce(6, Double.parseDouble(stk.nextToken()));
						((FrameElement)elm).setInitialNodalForce(7, Double.parseDouble(stk.nextToken()));
						((FrameElement)elm).setInitialNodalForce(8, Double.parseDouble(stk.nextToken()));
						((FrameElement)elm).setInitialNodalForce(9, Double.parseDouble(stk.nextToken()));
						((FrameElement)elm).setInitialNodalForce(10, Double.parseDouble(stk.nextToken()));
						((FrameElement)elm).setInitialNodalForce(11, Double.parseDouble(stk.nextToken()));
					}
					
					//Read "</Liberations>"
					else if (elmType==ELM_FRAME && "Liberations".equals(qName)) {
						stk = new StringTokenizer(content.toString(), " ");
						
						if (stk.nextToken().toLowerCase().equals("true"))
							((FrameElement)elm).setLiberation(0, true);
						else ((FrameElement)elm).setLiberation(0, false);
						
						if (stk.nextToken().toLowerCase().equals("true"))
							((FrameElement)elm).setLiberation(1, true);
						else ((FrameElement)elm).setLiberation(1, false);
						
						if (stk.nextToken().toLowerCase().equals("true"))
							((FrameElement)elm).setLiberation(2, true);
						else ((FrameElement)elm).setLiberation(2, false);
						
						if (stk.nextToken().toLowerCase().equals("true"))
							((FrameElement)elm).setLiberation(3, true);
						else ((FrameElement)elm).setLiberation(3, false);
						
						if (stk.nextToken().toLowerCase().equals("true"))
							((FrameElement)elm).setLiberation(4, true);
						else ((FrameElement)elm).setLiberation(4, false);
						
						if (stk.nextToken().toLowerCase().equals("true"))
							((FrameElement)elm).setLiberation(5, true);
						else ((FrameElement)elm).setLiberation(5, false);
						
						if (stk.nextToken().toLowerCase().equals("true"))
							((FrameElement)elm).setLiberation(6, true);
						else ((FrameElement)elm).setLiberation(6, false);
						
						if (stk.nextToken().toLowerCase().equals("true"))
							((FrameElement)elm).setLiberation(7, true);
						else ((FrameElement)elm).setLiberation(7, false);
						
						if (stk.nextToken().toLowerCase().equals("true"))
							((FrameElement)elm).setLiberation(8, true);
						else ((FrameElement)elm).setLiberation(8, false);
						
						if (stk.nextToken().toLowerCase().equals("true"))
							((FrameElement)elm).setLiberation(9, true);
						else ((FrameElement)elm).setLiberation(9, false);
						
						if (stk.nextToken().toLowerCase().equals("true"))
							((FrameElement)elm).setLiberation(10, true);
						else ((FrameElement)elm).setLiberation(10, false);
						
						if (stk.nextToken().toLowerCase().equals("true"))
							((FrameElement)elm).setLiberation(11, true);
						else ((FrameElement)elm).setLiberation(11, false);
						
					}
					
					//Read "</MyElmPointForce>"
					else if ("MyElmPointForce".equals(qName)) {
					}
					
					//Read "</ElmPointForce>"
					else if ("ElmPointForce".equals(qName)) {
						elm.add(elmPF);
					}
					
					//Read "</MyLineForce ...>"
					else if ("MyLineForce".equals(qName)) {
					}
					
					//Read "</MySurfaceForce ...>"
					else if ("MySurfaceForce".equals(qName)) {
					}
					
					//Read "</MyVolumeForce ...>"
					else if ("MyVolumeForce".equals(qName))	{
					}
					
					//Read "</LineElementForce ...>"
					else if ("LineElementForce".equals(qName)) {
						elm.addElmLineForce(ef);
					}
					
					//Read "</SurfaceElementForce ...>"
					else if ("SurfaceElementForce".equals(qName)) {
						elm.addElmSurfaceForce(ef);
					}
					
					//Read "</VolumeElementForce ...>"
					else if ("VolumeElementForce".equals(qName)) {
						elm.addElmVolumeForce(ef);
					}
					
					//Read "</Point>"
					else if ("Point".equals(qName)) {
						stk = new StringTokenizer(content.toString(), " ");
						coord.x = Double.parseDouble(stk.nextToken());
						if (stk.hasMoreTokens())
							coord.y = Double.parseDouble(stk.nextToken());
						if (stk.hasMoreTokens())
							coord.z = Double.parseDouble(stk.nextToken());
						elmPF.setCoord(coord);
					}
					
					//Read "</Force>"
					else if ("Force".equals(qName)) {
						stk = new StringTokenizer(content.toString(), " ");
						elmPF.setForce(0, Double.parseDouble(stk.nextToken()));
						elmPF.setForce(1, Double.parseDouble(stk.nextToken()));
						elmPF.setForce(2, Double.parseDouble(stk.nextToken()));
						elmPF.setForce(3, Double.parseDouble(stk.nextToken()));
						elmPF.setForce(4, Double.parseDouble(stk.nextToken()));
						elmPF.setForce(5, Double.parseDouble(stk.nextToken()));
					}
					
					//Read "</ElementForce>"
					else if ("ElementForce".equals(qName)) {
						elm.add(ef);
					}
					
					//Read "</PointForce ...>"
					else if ("PointForce".equals(qName)) {
						ef.add(pf);
					}
					
					//Read "</PointForceCoords ...>"
					else if ("PointForceCoords".equals(qName)) {
						stk = new StringTokenizer(content.toString(), " ");
						coord.x = Double.parseDouble(stk.nextToken());
						coord.y = Double.parseDouble(stk.nextToken());
						if (stk.hasMoreTokens())
							coord.z = Double.parseDouble(stk.nextToken());
						pf.setCoord(coord);
					}
					
					//Read "</PointForceLoad ...>"
					else if ("PointForceLoad".equals(qName))	{
						stk = new StringTokenizer(content.toString(), " ");
						pf.setForce(0, Double.parseDouble(stk.nextToken()));
						pf.setForce(1, Double.parseDouble(stk.nextToken()));
						pf.setForce(2, Double.parseDouble(stk.nextToken()));
						pf.setForce(3, Double.parseDouble(stk.nextToken()));
						pf.setForce(4, Double.parseDouble(stk.nextToken()));
						pf.setForce(5, Double.parseDouble(stk.nextToken()));
					}
					
					//Read "</GlobalAnalysisModel>"
					else if ("GlobalAnalysisModel".equals(qName)) {
						String type = content.toString();
						
						if (model.getAnalysisModel(type) != null)
							model.setGlobalAnalysisModel(model.getAnalysisModel(type));
						
						else {
							if (type.equals("PlaneFrame")) {
								anl = new PlaneFrame();
								model.add(anl);
							} else if (type.equals("PlaneTruss")) {
								anl = new PlaneTruss();
								model.add(anl);
							} else if (type.equals("Grid")) {
								anl = new Grid();
								model.add(anl);
							} else if (type.equals("Beam")) {
								anl = new Beam();
								model.add(anl);
							} else if (type.equals("SpaceFrame")) {
								anl = new SpaceFrame();
								model.add(anl);
							} else if (type.equals("SpaceTruss")) {
								anl = new SpaceTruss();
								model.add(anl);
							} else if (content.toString().equals("Line_1D")) {
								 anl = new Line_1D();
								 model.add(anl);
							} else if (content.toString().equals("Line_2D")) {
								 anl = new Line_2D();
								 model.add(anl);
							} else if (content.toString().equals("Line_3D")) {
								 anl = new Line_3D();
								 model.add(anl);
							} else if (content.toString().equals("PlaneStrainAnalysisM")) {
								 anl = new PlaneStrainAnalysisM();
								 model.add(anl);
							} else if (content.toString().equals("PlaneStressAnalysisM")) {
								 anl = new PlaneStressAnalysisM();
								 model.add(anl);
							} else if (content.toString().equals("AxiSymetricAnalysisM")) {
								 anl = new AxiSymetricAnalysisM();
								 model.add(anl);
							} else if (content.toString().equals("SolidAnalysisM")) {
								 anl = new SolidAnalysisM();
								 model.add(anl);
							}
							model.setGlobalAnalysisModel(anl);
						}
					}
					
					content = new StringBuffer();
				}
			});
			
		} catch (ParserConfigurationException pce) {
			parent.addOutputText("Could not create that parser.");
			parent.addOutputText(pce.getMessage());
		} catch (SAXException se) {
			parent.addOutputText("Problem with the SAX parser.");
			parent.addOutputText(se.getMessage());
		} catch (IOException ioe) {
			parent.addOutputText("Error reading file.");
			parent.addOutputText(ioe.getMessage());
		}
	}
	}
	

